package com.lazypeople.controller;

import com.lazypeople.application.TaskManager;
import com.lazypeople.domain.DownloadStatus;
import com.lazypeople.domain.DownloadTask;
import com.lazypeople.domain.DownloadSetting;
import com.lazypeople.service.DownloadService;
import com.lazypeople.service.impl.HttpDownloadService;
import com.lazypeople.service.impl.TorrentDownloadService;
import com.lazypeople.task.impl.HttpDownloadTask;
import com.lazypeople.util.FileUtils;
import com.lazypeople.util.ConfigUtils;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane; // Change VBox to BorderPane
import javafx.stage.DirectoryChooser;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.stage.Stage; // 添加缺失的导入语句
import javafx.fxml.FXMLLoader; // 添加缺失的导入语句
import javafx.scene.Parent; // 添加缺失的导入语句
import javafx.scene.Scene; // 添加缺失的导入语句
import javafx.stage.FileChooser; // 添加缺失的导入语句
import javafx.application.Platform; // 确保已导入 Platform 类
import javafx.stage.Modality; // 添加缺失的导入语句
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.Map;
import javafx.event.ActionEvent;
import javafx.beans.property.SimpleStringProperty;
import javafx.scene.layout.HBox;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.scene.text.Text;
import javafx.geometry.Pos;

public class DownloadController {
    @FXML
    private ResourceBundle resources;

    @FXML
    private URL location;

    @FXML
    private BorderPane root;

    @FXML
    private TextField urlInput;

    @FXML
    private TableView<DownloadTask> downloadTable; // 添加此行声明

    @FXML
    private TextField savePathInput;

    @FXML
    private Button browseButton;

    @FXML
    private Spinner<Integer> threadCountSpinner;

    @FXML
    private Button startDownloadButton;

    @FXML
    private ProgressBar downloadProgressBar;

    @FXML
    private Label progressLabel;

    @FXML
    private ListView<String> taskListView; // 根据实际数据类型调整泛型

    @FXML
    private TableColumn<DownloadTask, String> fileNameColumn;
    @FXML
    private TableColumn<DownloadTask, String> urlColumn;
    @FXML
    private TableColumn<DownloadTask, String> savePathColumn;
    @FXML
    private TableColumn<DownloadTask, String> statusColumn;
    @FXML
    private TableColumn<DownloadTask, Double> progressColumn; //

    private final TaskManager taskManager = TaskManager.getInstance();
    private final DownloadService httpDownloadService = new HttpDownloadService();
    private final DownloadService torrentDownloadService = new TorrentDownloadService();
    private final DownloadSetting downloadSetting = ConfigUtils.loadDownloadSetting();
    private String currentTaskId;
    private static final Logger logger = LoggerFactory.getLogger(DownloadController.class);
    // 初始化表格数据
    private ObservableList<DownloadTask> tasks;

    @FXML
    void initialize() {
        // 添加CSS样式表
        String cssPath = getClass().getResource("styles.css").toExternalForm();
        root.getStylesheets().add(cssPath);

        // 初始化线程数选择器(1-10线程)
        SpinnerValueFactory.IntegerSpinnerValueFactory valueFactory = new SpinnerValueFactory.IntegerSpinnerValueFactory(
                1, 10, 4);
        threadCountSpinner.setValueFactory(valueFactory);
        threadCountSpinner.setEditable(true);
        threadCountSpinner.getEditor().setTextFormatter(
                new TextFormatter<>(valueFactory.getConverter(), valueFactory.getValue()));
        // 初始化进度条
        downloadProgressBar.setProgress(0);
        savePathInput.setText(downloadSetting.getDefaultSavePath());
        // 设置任务管理器监听器
        taskManager.addTaskStatusListener(new TaskStatusListenerImpl());
        // 绑定列表点击事件
        taskListView.setOnMouseClicked(this::onTaskItemClicked);

        // 初始化表格数据
        tasks = FXCollections.observableArrayList();
        downloadTable.setItems(tasks);

        // 添加任务管理器监听器，更新表格数据
        taskManager.addTaskStatusListener(new TaskStatusListenerImpl() {
            @Override
            public void onStatusUpdated(String taskId, DownloadStatus status) {
                super.onStatusUpdated(taskId, status);
                // 更新表格数据 - 修复Map转Collection的错误
                Platform.runLater(() -> {
                    tasks.setAll(taskManager.getAllTasks().values());
                });
            }
        });
        initTable();
        bindData();
        // 初始化进度列单元格工厂
        initProgressColumn();
    }

    // 初始化进度列
    private void initProgressColumn() {
        // ... existing code ...
        progressColumn.setCellFactory(column -> new TableCell<DownloadTask, Double>() {
            private final ProgressBar progressBar = new ProgressBar();
            private final Text percentageText = new Text();
            private final HBox container = new HBox(5, progressBar, percentageText);

            {
                progressBar.setPrefWidth(100);
                container.setAlignment(Pos.CENTER_LEFT);
            }

            @Override
            protected void updateItem(Double progress, boolean empty) {
                super.updateItem(progress, empty);
                if (empty || progress == null) {
                    setGraphic(null);
                } else {
                    progressBar.setProgress(progress);
                    percentageText.setText(String.format("%.1f%%", progress * 100));
                    setGraphic(container);
                }
            }
        });
        // ... existing code ...

        // 绑定单元格值工厂到任务进度属性
        progressColumn.setCellValueFactory(cellData -> cellData.getValue().progressProperty().asObject());
    }

    // 更新进度的回调方法（已存在）
    public void onProgressUpdated(String taskId, long downloaded, long total, float progress) {
        // 在UI线程中更新进度
        Platform.runLater(() -> {
            // 添加调试日志（关键修复）
            logger.debug("Progress update received - TaskId: {}. Progress: {}", taskId, progress);

            // 查找任务并更新进度
            tasks.stream()
                    .filter(task -> task.getTaskId().equals(taskId))
                    .findFirst()
                    .ifPresentOrElse(task -> {
                        // 确保进度值在0-1范围内（关键修复）
                        double normalizedProgress = Math.max(0, Math.min(1, progress));
                        task.setProgress(normalizedProgress);
                        logger.info("Task {} progress updated to {}", taskId, normalizedProgress);
                    }, () -> {
                        logger.warn("Task not found for ID: {}", taskId);
                    });
        });
    }

    private void initTable() {
        // 操作列单元格工厂 - 完整语法验证版本
        // 修复操作列单元格工厂实现
        actionColumn.setCellFactory(
                new javafx.util.Callback<TableColumn<DownloadTask, DownloadTask>, TableCell<DownloadTask, DownloadTask>>() {
                    @Override // 确保此注解正确应用
                    public TableCell<DownloadTask, DownloadTask> call(TableColumn<DownloadTask, DownloadTask> param) {
                        return new TableCell<DownloadTask, DownloadTask>() {
                            private final Button btnDownload = new Button("下载");
                            {
                                btnDownload.setOnAction(event -> {
                                    DownloadTask task = getTableView().getItems().get(getIndex());
                                    if (task != null) {
                                        logger.info("任务操作: {}", task.getSaveFile().getName());
                                        // 添加实际操作逻辑
                                    }
                                });
                            }
                            private final Button btnPause = new Button("暂停");
                            {
                                btnPause.setOnAction(event -> {
                                    DownloadTask task = getTableView().getItems().get(getIndex());
                                    if (task != null) {
                                        logger.info("任务操作: {}", task.getSaveFile().getName());
                                        // 添加实际操作逻辑
                                    }
                                });
                            }
                            private final Button btnResume = new Button("恢复");
                            {
                                btnResume.setOnAction(event -> {
                                    DownloadTask task = getTableView().getItems().get(getIndex());
                                    if (task != null) {
                                        logger.info("任务操作: {}", task.getSaveFile().getName());
                                        // 添加实际操作逻辑
                                    }
                                });
                            }
                            private final Button btnCancel = new Button("取消");
                            {
                                btnCancel.setOnAction(event -> {
                                    DownloadTask task = getTableView().getItems().get(getIndex());
                                    if (task != null) {
                                        logger.info("任务操作: {}", task.getSaveFile().getName());
                                        // 添加实际操作逻辑
                                    }
                                });
                            }

                            // 创建HBox容器存放所有按钮
                            private final HBox buttonBox = new HBox(5); // 5像素间距
                            {
                                buttonBox.getChildren().addAll(btnDownload, btnPause, btnResume, btnCancel);
                            }

                            @Override
                            protected void updateItem(DownloadTask item, boolean empty) {
                                super.updateItem(item, empty);
                                // 设置整个按钮容器为单元格图形
                                setGraphic(empty ? null : buttonBox);
                            }
                        };
                    }
                });
    }

    private void bindData() {
        // 绑定filNameColumn到DownloadTask的getSaveFile().getName()
        // 添加缺失的 @FXML 声明
        fileNameColumn.setCellValueFactory(cellData -> {
            DownloadTask task = cellData.getValue();
            if (task.getSaveFile() != null) {
                return new SimpleStringProperty(task.getSaveFile().getName());
            } else {
                return new SimpleStringProperty(""); // 处理null情况
            }
        });

        // 添加缺失的 @FXML 声明
        savePathColumn.setCellValueFactory(cellData -> {
            DownloadTask task = cellData.getValue();
            if (task.getSaveFile() != null) {
                return new SimpleStringProperty(task.getSaveFile().getAbsolutePath());
            } else {
                return new SimpleStringProperty(""); // 处理null情况
            }
        });
        urlColumn.setCellValueFactory(cellData -> {
            DownloadTask task = cellData.getValue();
            if (task.getSaveFile() != null) {
                return new SimpleStringProperty(task.getUrl());
            } else {
                return new SimpleStringProperty(""); // 处理null情况
            }
        });
        // 添加缺失的 @FXML 声明
        statusColumn.setCellValueFactory(cellData -> {
            DownloadTask task = cellData.getValue();
            if (task.getSaveFile() != null) {
                return new SimpleStringProperty(task.getStatus().getStatusName());
            } else {
                return new SimpleStringProperty(""); // 处理null情况
            }
        });
    }

    private void startDownload(DownloadTask task) {
        // 将原有onDownloadButtonClick中的下载逻辑迁移到这里
        if (task != null) {
            TaskManager.getInstance().addTask(task);
            // 可以添加其他下载相关逻辑
        }
    }

    // 将MouseEvent改为ActionEvent
    @FXML
    void onBrowseButtonClicked(ActionEvent event) {
        DirectoryChooser directoryChooser = new DirectoryChooser();
        directoryChooser.setTitle("选择保存目录");
        File selectedDirectory = directoryChooser.showDialog(savePathInput.getScene().getWindow());
        if (selectedDirectory != null) {
            savePathInput.setText(selectedDirectory.getAbsolutePath());
        }
    }

    // 将MouseEvent改为ActionEvent
    @FXML
    void onStartDownloadClicked(ActionEvent event) {
        String url = urlInput.getText().trim();
        String savePath = savePathInput.getText().trim();
        int threadCount = threadCountSpinner.getValue();

        // 输入验证
        if (url.isEmpty() || savePath.isEmpty()) {
            showAlert(Alert.AlertType.ERROR, "错误", "输入不完整", "URL和保存路径不能为空");
            return;
        }

        if (!FileUtils.isValidDirectory(savePath)) {
            showAlert(Alert.AlertType.ERROR, "错误", "路径无效", "请选择有效的保存目录");
            return;
        }

        try {
            // 根据URL类型创建不同的下载任务
            DownloadTask task;
            String fileName = FileUtils.getFileNameFromUrl(url);
            File saveFile = new File(savePath, fileName);

            if (isTorrentUrl(url)) {
                task = torrentDownloadService.createTask(url, saveFile, threadCount);
            } else {
                // 修复createTask调用，移除多余的线程数参数
                task = httpDownloadService.createTask(url, saveFile, threadCount);
            }

            // 添加任务到管理器
            currentTaskId = taskManager.addTask(task);
            tasks.add(task);
            logger.info("Added new task with ID:{}", currentTaskId);
            taskListView.getItems().add(currentTaskId + ": " + new URL(url).getFile());
            logger.info("开始下载: {}", url);

        } catch (MalformedURLException e) {
            logger.error("URL格式错误: {}", e.getMessage());
        } catch (Exception e) {
            logger.error("创建任务失败: {}", e.getMessage());
        }
    }

    // 暂停按钮
    @FXML
    void onPauseClicked(ActionEvent event) {
        if (currentTaskId != null) {
            boolean success = taskManager.pauseTask(currentTaskId);
            if (success) {
                // logArea.appendText("任务已暂停\n");
                showAlert(Alert.AlertType.INFORMATION, "提示", "操作信息", "任务已暂停");
            } else {
                showAlert(Alert.AlertType.WARNING, "警告", "操作失败", "无法暂停任务或任务不存在");
            }
        }
    }

    // 恢复按钮
    @FXML
    void onResumeClicked(ActionEvent event) {
        if (currentTaskId != null) {
            boolean success = taskManager.resumeTask(currentTaskId);
            if (success) {
                // logArea.appendText("任务已恢复\n");
                showAlert(Alert.AlertType.INFORMATION, "提示", "操作信息", "任务已恢复");
            } else {
                showAlert(Alert.AlertType.WARNING, "警告", "操作失败", "无法恢复任务或任务不存在");
            }
        }
    }

    // 取消按钮
    @FXML
    void onCancelClicked(ActionEvent event) {
        if (currentTaskId != null) {
            boolean success = taskManager.cancelTask(currentTaskId);
            if (success) {
                // logArea.appendText("任务已取消\n");
                showAlert(Alert.AlertType.INFORMATION, "提示", "操作信息", "任务已取消");
                taskListView.getItems().removeIf(item -> item.startsWith(currentTaskId));
                resetDownloadUI();
            } else {
                showAlert(Alert.AlertType.WARNING, "警告", "操作失败", "无法取消任务或任务不存在");
            }
        }
    }

    private void onTaskItemClicked(MouseEvent event) {
        String selectedItem = taskListView.getSelectionModel().getSelectedItem();
        if (selectedItem != null && event.getClickCount() == 1) {
            currentTaskId = selectedItem.split(":")[0];
            DownloadStatus status = taskManager.getTaskStatus(currentTaskId);
            // logArea.appendText("选中任务: " + currentTaskId + " 状态: " + status + "\n");
            showAlert(Alert.AlertType.INFORMATION, "提示", "操作信息", "选中任务: " + currentTaskId + " 状态: " + status + "\n");
        }
    }

    private boolean isTorrentUrl(String url) {
        return url.startsWith("magnet:") || url.endsWith(".torrent");
    }

    private void showAlert(Alert.AlertType type, String title, String header, String content) {
        Alert alert = new Alert(type);
        alert.setTitle(title);
        alert.setHeaderText(header);
        alert.setContentText(content);
        alert.setHeight(200);
        alert.showAndWait();
    }

    private void resetDownloadUI() {
        downloadProgressBar.setProgress(0);
        progressLabel.setText("0%");
        currentTaskId = null;
    }

    // 任务状态监听器实现类
    private class TaskStatusListenerImpl implements TaskManager.TaskStatusListener {
        @Override
        public void onStatusUpdated(String taskId, DownloadStatus status) {
            if (taskId.equals(currentTaskId)) {
                // logArea.appendText("任务状态变更: " + status + "\n");
                logger.info("任务状态变更: {}", status.getStatusName());
                // showAlert(Alert.AlertType.INFORMATION, "提示", "操作信息",
                // "任务状态变更: " + status + "\n");

                if (status == DownloadStatus.COMPLETED) {
                    logger.info("文件已成功下载: {}", taskManager.getAllTasks().get(currentTaskId).getUrl());

                    // showAlert(Alert.AlertType.INFORMATION, "成功", "下载完成", "文件已成功下载");
                    resetDownloadUI();
                    taskListView.getItems().removeIf(item -> item.startsWith(taskId));
                } else if (status == DownloadStatus.FAILED) {
                    logger.info("文件下载过程中出现错误: {}", taskManager.getAllTasks().get(currentTaskId).getUrl());
                    // showAlert(Alert.AlertType.ERROR, "失败", "下载失败", "文件下载过程中出现错误");
                }
            }
        }

        @Override
        public void onProgressUpdated(String taskId, long downloaded, long total, float progress) {
            logger.debug("TaskStatusListenerImpl->onProgressUpdated");
            tasks.stream()
                    .filter(task -> task.getTaskId().equals(taskId))
                    .findFirst()
                    .ifPresentOrElse(task -> {
                        // 确保进度值在0-1范围内（关键修复）
                        double normalizedProgress = Math.max(0, Math.min(1, progress));
                        task.setProgress(normalizedProgress);
                        logger.info("Task {} progress updated to {}", taskId, normalizedProgress);
                    }, () -> {
                        logger.warn("Task not found for ID: {}", taskId);
                    });

            float totalProgress = 0F;
            int taskCount = 0;
            long totalDownloaded = 0L;
            long totalFileSize = 0L;

            for (DownloadTask task : taskManager.getAllTasks().values()) {
                if (task instanceof HttpDownloadTask) {
                    HttpDownloadTask httpTask = (HttpDownloadTask) task;

                    totalProgress += httpTask.getProgress();
                    totalFileSize += httpTask.getTotalBytes();
                    totalDownloaded += httpTask.getDownloadedBytes();
                }
                taskCount++;
            }

            if (taskCount > 0) {
                downloadProgressBar.setProgress(progress);
            } else {
                downloadProgressBar.setProgress(-1); // 不确定进度时显示动画
            }

            String progressText = String.format("%.2f%% (%s/%s)",
                    totalProgress * 100,
                    FileUtils.formatFileSize(totalDownloaded),
                    FileUtils.formatFileSize(totalFileSize));

            progressLabel.setText(progressText);

        }
    }

    // 添加URL设置方法
    public void setDownloadUrl(String url) {
        if (urlInput != null) {
            urlInput.setText(url);
            urlInput.requestFocus(); // 聚焦到输入框
            // 自动选择保存路径（可选功能）
            if (savePathInput.getText().isEmpty()) {
                String defaultPath = System.getProperty("user.home") + File.separator + "Downloads";
                savePathInput.setText(defaultPath);
            }
        }
    }

    // 添加菜单事件处理方法
    @FXML
    void onMenuHelp() {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("帮助");
        alert.setHeaderText("使用帮助");
        alert.setContentText("1. 在下载地址栏输入URL\n2. 选择保存路径\n3. 点击开始下载按钮\n4. 在任务列表中查看下载进度");
        alert.showAndWait();
    }

    @FXML
    void onMenuAbout() {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("关于");
        alert.setHeaderText("懒人下载器 V1.0");
        alert.setContentText("一个简单高效的下载工具\n支持HTTP和磁力链接下载");
        alert.showAndWait();
    }

    // Add missing onMenuOpen method
    @FXML
    void onMenuOpen() {
        // Implement file open functionality here
        // Example: Show file chooser dialog
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("打开文件");
        File selectedFile = fileChooser.showOpenDialog(null);
        if (selectedFile != null) {
            // Handle selected file (e.g. read URL from file)
            urlInput.setText(selectedFile.getAbsolutePath());
        }
    }

    // Add missing onMenuExit method
    @FXML
    void onMenuExit() {
        // Close the application
        // 添加缺失的导入语句，此处需要导入 javafx.application.Platform
        Platform.exit();
    }

    @FXML
    void onMenuSettings() throws Exception {
        Stage stage = new Stage();
        // 确保SettingsController.fxml文件存在于指定路径
        FXMLLoader loader = new FXMLLoader(
                getClass().getResource("/com/lazypeople/controller/SettingsController.fxml"));
        Parent root = loader.load();
        stage.setTitle("设置");
        stage.setScene(new Scene(root, 400, 300)); // 设置适当大小
        stage.initModality(Modality.APPLICATION_MODAL); // 模态窗口
        stage.showAndWait();
    }

    @FXML
    public void handleActionButton(ActionEvent event) {

    }

    // 移除所有现有actionColumn相关代码，替换为以下完整实现
    @FXML
    private TableColumn<DownloadTask, DownloadTask> actionColumn;

    // 辅助方法：显示错误对话框
    private void showErrorAlert(String title, String header, String content) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle(title);
        alert.setHeaderText(header);
        alert.setContentText(content);
        alert.showAndWait();
    }

    @FXML
    private void onDownloadButtonClick(ActionEvent event) {
        // Your download logic here
        // Example implementation:

    }

    // Add these methods to the DownloadController class
    @FXML
    void onOngoingTasksClicked(ActionEvent event) {
        // Filter and display ongoing tasks
        updateTaskTableView(DownloadStatus.DOWNLOADING, DownloadStatus.PAUSED);
    }

    // 添加已完成任务处理方法
    @FXML
    void onCompletedTasksClicked(ActionEvent event) {
        // 筛选并显示已完成任务
        updateTaskTableView(DownloadStatus.COMPLETED);
    }

    // 添加任务筛选辅助方法
    private void updateTaskTableView(DownloadStatus... statuses) {
        Set<DownloadStatus> statusSet = new HashSet<>(Arrays.asList(statuses));
        ObservableList<DownloadTask> filteredTasks = FXCollections.observableArrayList();

        for (Map.Entry<String, DownloadTask> entry : taskManager.getAllTasks().entrySet()) {
            if (statusSet.contains(entry.getValue().getStatus())) {
                filteredTasks.add(entry.getValue());
            }
        }

        downloadTable.setItems(filteredTasks);
    }
}